﻿using System;
using System.Linq;
using System.Collections.Generic;
using PharmacyPharnet.Core;
using Pharmacy.ExceptionHandling;
using System.Windows.Forms;
using DevExpress.XtraGrid;
using Pharmacy.Data.Repositories;
using Pharmacy.Data;
using Pharmacy.Ultilities;
using Pharmacy.Data.Entity;
using Pharmacy.Business.Generator;
using PharmacyPharnet.MasterData;
using DevExpress.XtraEditors;
using Pharmacy.Business;
using Pharmacy.Ultilities.Resources;
using Pharmacy.Data.Core;



namespace PharmacyPharnet.KinhDoanh
{
    public partial class FrmPhieuDatHangChiTiet : FrmEditBase
    {
        #region Declarations
        IObjectContext pharmacyContext;
        PhieuDatHangBO pdhBO;
        PhieuDatHang currentPhieuDatHang;
        PhieuDatHang originalPhieuDatHang;
        MasterItemRepository rMasterItem;
        /// <summary>
        /// Keep track all PhieudatHangChiTiets are temporarily deleted in form.
        /// </summary>
        List<PhieuDatHangChiTiet> lstPhieuDatHangChiTietDeleted;
        bool applyAllVAT = false;
        bool applyAllDiscount = false;
        #endregion

        #region Constructors
        public FrmPhieuDatHangChiTiet()
        {
            InitializeComponent();
        }

        public FrmPhieuDatHangChiTiet(Enums.ActionForm actionForm)
            : this()
        {
            CurrentAction = actionForm;            
        }

        public FrmPhieuDatHangChiTiet(IObjectContext objectContext, PhieuDatHang objPhieuDatHang, Enums.ActionForm actionForm)
            : this(actionForm)
        {
            pharmacyContext = objectContext;
            currentPhieuDatHang = objPhieuDatHang;            
        }
        #endregion

        #region Override Methods
        protected override void InitializeBO()
        {
            if (pharmacyContext == null)
                pharmacyContext = ObjectContextFactory.CreatePharmacyContext(Global.UserName, Global.CurrentConnectionString);
            if (pdhBO == null)
                pdhBO = new PhieuDatHangBO(pharmacyContext);
        }

        protected override void PopulateStaticData()
        {
            luePDHdetailItem.DataSource = LoadItemList(0);
            LoadMasterLocationList(0);
            LoadVendorList(0);

            lstPhieuDatHangChiTietDeleted = new List<PhieuDatHangChiTiet>();
        }

        protected override void PopulateData()
        {
            if (CurrentAction == Enums.ActionForm.None)
                CurrentAction = Enums.ActionForm.New;
            BindDataToControl();
        }
        #endregion

        #region Custom Methods
        private void RegisterEventHandlers()
        {
            btnCancel.Click += btnCancel_Click;
            btnClose.Click += btnClose_Click;
            btnDelete.Click += btnDelete_Click;
            btnNew.Click += btnNew_Click;
            btnSave.Click += btnSave_Click;
        }

        /// <summary>
        /// Thiết lập 1 số giá trị default cho form khi tạo mới phiếu báo giá như : 
        /// Mã Số Phiếu; Ngày lập
        /// </summary>
        private void SetDefaultValue()
        {
            DateTime currentdate = pharmacyContext.GetCurrentDateTime();
            txtPDHNumber.Text = IdentityGeneratorHelper.GetNextNumber(Enums.GeneratorObjectType.PhieuDatHangGenerator, currentdate, null, pharmacyContext);
            dtePDHDocumentDate.EditValue = currentdate;
            dtePDHDocumentDate.Focus();
        }

        /// <summary>
        /// Enable / Disable các control trong form. 
        /// Nếu CurrentAction = New/Edit : cho phép chỉnh sửa thông tin; ngược lại disable các control
        /// </summary>
        private void EnableControlToEdit()
        {
            bool enable = true;
            if (CurrentAction == Enums.ActionForm.View)
            {
                enable = false;
            }
            dtePDHDocumentDate.Properties.ReadOnly = !enable;
            txtPDHNote.Properties.ReadOnly = !enable;
            txtPDHTienCK.Properties.ReadOnly = !enable;
            txtPDHTienVAT.Properties.ReadOnly = !enable;
            luePDHMasterLocation.Properties.ReadOnly = !enable;
            luePDHVendor.Properties.ReadOnly = !enable;
            grvPDHDetail.OptionsBehavior.Editable = enable;
        }

        /// <summary>
        /// Load danh sách sản phẩm trong hệ thống
        /// </summary>
        private List<MasterItem> LoadItemList(int selectedID)
        {
            rMasterItem = new MasterItemRepository(pharmacyContext, MergeOption.Overrive);
            return rMasterItem.AsQueryable().ToList();
        }

        /// <summary>
        /// Load danh sách nhà cung cấp trong hệ thống
        /// </summary>
        private void LoadVendorList(int selectedID)
        {
            VendorRepository rVendor = new VendorRepository(pharmacyContext, MergeOption.Overrive);
            luePDHVendor.Properties.DataSource = rVendor.AsQueryable().ToList();
            luePDHVendor.EditValue = selectedID;

        }

        /// <summary>
        /// Load danh sách nơi được báo giá (Location) trong hệ thống
        /// </summary>
        private void LoadMasterLocationList(int selectedID)
        {
            MasterLocationRepository rMasterLocation = new MasterLocationRepository(pharmacyContext, MergeOption.Overrive);
            luePDHMasterLocation.Properties.DataSource = rMasterLocation.AsQueryable().ToList();
            luePDHMasterLocation.EditValue = selectedID;

        }

        /// <summary>
        /// Hiển thị thông tin chi tiết của Nhà Cung Cấp, Nơi Báo Giá
        /// </summary>
        private void DisplayInformationOfObject(object viewObject)
        {
            if (viewObject.ToString() == typeof(Vendor).FullName)
            {
                Vendor v = viewObject as Vendor;
                ShippingInfo sh = v.ShippingInfo;
                ContactInfo contact = v.ContactInfo;
                mmeInformationDetail.Text = string.Format("Nhà cung cấp: {0} | Số ĐT: {1} | Fax : {2} \r\n Liên hệ : {3} | Số ĐT : {4} | Cell : {5}",
                    v.FullName, sh != null ? sh.Phone: string.Empty, sh != null ? sh.Fax: string.Empty, 
                    contact != null? contact.Name : string.Empty, contact != null? contact.Phone : string.Empty, contact != null? contact.MobilePhone: string.Empty);
            }
            else if (viewObject.ToString() == typeof(MasterLocation).FullName)
            {
                MasterLocation m = viewObject as MasterLocation;
                ShippingInfo sh = m.ShippingInfo;
                ContactInfo contact = m.ContactInfo;
                mmeInformationDetail.Text = string.Format("Nơi được báo giá: {0} | Số ĐT: {1} | Fax : {2} \r\n Liên hệ : {3} | Số ĐT : {4} | Cell : {5}",
                                                            m.Name, sh != null ? sh.Phone : string.Empty, sh != null ? sh.Fax : string.Empty,
                                                            contact != null ? contact.Name : string.Empty, contact != null ? contact.Phone : string.Empty, 
                                                            contact != null ? contact.MobilePhone : string.Empty);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void BindDataToControl()
        {
            if (CurrentAction == Enums.ActionForm.New)
            {
                currentPhieuDatHang = new PhieuDatHang() { PhieuDatHangChiTiets = new System.Data.Objects.DataClasses.EntityCollection<PhieuDatHangChiTiet>() };
            }
            txtPDHNote.Text = currentPhieuDatHang.Note;
            txtPDHNumber.Text = currentPhieuDatHang.Code;
            txtPDHTienCK.EditValue = currentPhieuDatHang.TotalDiscountAmount;
            txtPDHTienTongCong.EditValue = currentPhieuDatHang.TotalAmountBeforeVAT;
            txtPDHTienTruocVAT.EditValue = currentPhieuDatHang.TotalAmount;
            txtPDHTienVAT.EditValue = currentPhieuDatHang.TotalVATAmount;
            luePDHMasterLocation.EditValue = currentPhieuDatHang.MasterLocation != null ? currentPhieuDatHang.MasterLocation.ID : -1;
            luePDHVendor.EditValue = currentPhieuDatHang.Vendor != null ? currentPhieuDatHang.Vendor.ID : -1;
            grdPDHDetail.DataSource = currentPhieuDatHang.PhieuDatHangChiTiets;            
        }

        /// <summary>
        /// 
        /// </summary>
        private void BindControlToData()
        {
            currentPhieuDatHang.Note = txtPDHNote.Text.Trim();
            currentPhieuDatHang.Code = txtPDHNumber.Text.Trim();
            currentPhieuDatHang.DocumentDate = Convert.ToDateTime(dtePDHDocumentDate.EditValue);
            currentPhieuDatHang.TotalDiscountAmount = Convert.ToDecimal(txtPDHTienCK.EditValue);
            currentPhieuDatHang.TotalAmountBeforeVAT = Convert.ToDecimal(txtPDHTienTruocVAT.EditValue);
            currentPhieuDatHang.TotalAmount = Convert.ToDecimal(txtPDHTienTongCong.EditValue);
            //txtPDHTienTruocVAT.EditValue = currentPhieuDatHang.TotalAmount - currentPhieuDatHang.TotalDiscountAmount + currentPhieuDatHang.TotalVATAmount;
            currentPhieuDatHang.TotalVATAmount = Convert.ToDecimal(txtPDHTienVAT.EditValue);
            currentPhieuDatHang.MasterLocation = luePDHMasterLocation.EditValue != null ? luePDHMasterLocation.Properties.GetDataSourceRowByKeyValue(luePDHMasterLocation.EditValue) as MasterLocation : null;
            currentPhieuDatHang.Vendor = luePDHVendor.EditValue != null ? luePDHVendor.Properties.GetDataSourceRowByKeyValue(luePDHVendor.EditValue) as Vendor:null;
            if (CurrentAction == Enums.ActionForm.New)
                currentPhieuDatHang.Status = (int)Enums.PhieuDatHangStatus.New;
        }

        /// <summary>
        /// Tính giá tiền sau khi nhập đơn giá, VAT, chiết khấu của 1 dòng sản phẩm
        /// </summary>
        private void CalculateAmountForPhieuDatHangDetail(PhieuDatHangChiTiet pdhChiTiet)
        {
            decimal amountBeforeVAT = 0;
            amountBeforeVAT = pdhChiTiet.UnitCost.GetValueOrDefault() * pdhChiTiet.Quantity.GetValueOrDefault();
            pdhChiTiet.AmountBeforeVAT = amountBeforeVAT;
            pdhChiTiet.DiscountAmount = amountBeforeVAT * pdhChiTiet.DiscountRate.GetValueOrDefault() / 100;
            pdhChiTiet.VATAmount = (amountBeforeVAT - pdhChiTiet.DiscountAmount.GetValueOrDefault()) * pdhChiTiet.VATRate.GetValueOrDefault() / 100;
            pdhChiTiet.Amount = (amountBeforeVAT - pdhChiTiet.DiscountAmount.GetValueOrDefault() + pdhChiTiet.VATAmount.GetValueOrDefault());

        }

        /// <summary>
        /// Tính giá tiền sau khi nhập đơn giá, VAT, chiết khấu của toàn bộ phiếu báo giá
        /// </summary>
        private void CalculateAmountForPhieuDatHang()
        {
            decimal totalAmount = 0;
            decimal totalAmountBeforeVAT = 0;
            decimal totalVATAmount = 0;
            decimal totalVATRate = 0;
            decimal totalDiscountAmount = 0;
            decimal totalDiscountRate = 0;
            foreach (PhieuDatHangChiTiet pdhChiTiet in currentPhieuDatHang.PhieuDatHangChiTiets)
            {
                CalculateAmountForPhieuDatHangDetail(pdhChiTiet);
                totalAmount += pdhChiTiet.Amount.GetValueOrDefault();
                totalAmountBeforeVAT += pdhChiTiet.AmountBeforeVAT.GetValueOrDefault();
                totalDiscountRate += pdhChiTiet.DiscountRate.GetValueOrDefault();
                totalDiscountAmount += pdhChiTiet.DiscountAmount.GetValueOrDefault();
                totalVATAmount += pdhChiTiet.VATAmount.GetValueOrDefault();
                totalVATRate += pdhChiTiet.VATRate.GetValueOrDefault();
            }
            txtPDHTienTruocVAT.EditValue = currentPhieuDatHang.TotalAmountBeforeVAT = totalAmountBeforeVAT;
            txtPDHTienCK.EditValue = currentPhieuDatHang.TotalDiscountAmount = totalDiscountAmount;
            currentPhieuDatHang.TotalDiscountRate = totalDiscountRate;
            txtPDHTienVAT.EditValue = currentPhieuDatHang.TotalVATAmount = totalVATAmount;
            currentPhieuDatHang.TotalVATRate = totalVATRate;
            txtPDHTienTongCong.EditValue = currentPhieuDatHang.TotalAmount = totalAmount;
        }

        /// <summary>
        /// Tất cả detail có cùng discount rate và VAT rate
        /// </summary>
        private void ApplyAllDiscountAndVAT(decimal discountRate, decimal vatRate)
        {
            foreach (PhieuDatHangChiTiet pdhChiTiet in currentPhieuDatHang.PhieuDatHangChiTiets)
            {
                if (applyAllVAT)
                    pdhChiTiet.VATRate = vatRate;
                else if (applyAllDiscount)
                    pdhChiTiet.DiscountRate = discountRate;
            }

            CalculateAmountForPhieuDatHang();

        }

        private void ResetAllData()
        {
            if (CurrentAction == Enums.ActionForm.New)
            {
                currentPhieuDatHang = new PhieuDatHang();
            }
            else if (CurrentAction == Enums.ActionForm.Edit)
            {
                if (currentPhieuDatHang.PhieuDatHangChiTiets != null && currentPhieuDatHang.PhieuDatHangChiTiets.Count > 0)
                {
                    List<PhieuDatHangChiTiet> lstChiTiet = currentPhieuDatHang.PhieuDatHangChiTiets.ToList();
                    PhieuDatHangChiTiet pbgChiTiet;
                    for (int i = lstChiTiet.Count - 1; i >= 0; i--)
                    {
                        pbgChiTiet = lstChiTiet[i];
                        if (pbgChiTiet.EntityState == System.Data.EntityState.Added)
                            currentPhieuDatHang.PhieuDatHangChiTiets.Remove(pbgChiTiet);
                    }

                }

                if (lstPhieuDatHangChiTietDeleted.Count > 0)
                {
                    foreach (PhieuDatHangChiTiet pdhDetail in lstPhieuDatHangChiTietDeleted)
                    {
                        pdhDetail.PhieuDatHang = currentPhieuDatHang;
                        currentPhieuDatHang.PhieuDatHangChiTiets.Attach(pdhDetail);
                    }
                    lstPhieuDatHangChiTietDeleted.Clear();
                }

                pharmacyContext.Reload(System.Data.Objects.RefreshMode.StoreWins, currentPhieuDatHang);
                pharmacyContext.Reload(System.Data.Objects.RefreshMode.StoreWins, currentPhieuDatHang.PhieuDatHangChiTiets);
            }
            BindDataToControl();
        }

        private bool ValidateData()
        {
            bool isValid = true;
            if (luePDHMasterLocation.EditValue == null || luePDHMasterLocation.Text.Trim().Length <= 0)
            {
                luePDHMasterLocation.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_EMPTYINFORMATION), SR.Instance.GetString(Constant.ENT_MASTERLOCATION));
                isValid = false;
            }
            //Reload Cửa Hàng
            else if (luePDHMasterLocation.EditValue != null)
            {
                MasterLocationRepository rMasterLocation = new MasterLocationRepository(pharmacyContext);
                int selectedMasterItemGroupID = (luePDHMasterLocation.Properties.GetDataSourceRowByKeyValue(luePDHMasterLocation.EditValue) as MasterLocation).ID;
                MasterLocation objTemp = rMasterLocation.AsQueryable().Where(m => m.ID == selectedMasterItemGroupID).First();
                if (objTemp == null)
                {
                    luePDHMasterLocation.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_OBJECTISDELETED), SR.Instance.GetString(Constant.ENT_MASTERLOCATION));
                    isValid = false;
                }
            }
            if (luePDHVendor.EditValue == null || luePDHVendor.Text.Trim().Length <= 0)
            {
                luePDHVendor.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_EMPTYINFORMATION), SR.Instance.GetString(Constant.ENT_VENDOR));
                isValid = false;
            }
            //Reload Nhà Cung Cấp
            else if (luePDHVendor.EditValue != null)
            {
                VendorRepository rVendor = new VendorRepository(pharmacyContext);
                int selectedMasterItemGroupID = (luePDHVendor.Properties.GetDataSourceRowByKeyValue(luePDHVendor.EditValue) as Vendor).ID;
                Vendor objTemp = rVendor.AsQueryable().Where(m => m.ID == selectedMasterItemGroupID).First();
                if (objTemp == null)
                {
                    luePDHVendor.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_OBJECTISDELETED), SR.Instance.GetString(Constant.ENT_VENDOR));
                    isValid = false;
                }
            }

            // Validate Đơn Giá của item
            List<PhieuDatHangChiTiet> lstPDHChiTiet = currentPhieuDatHang.PhieuDatHangChiTiets.ToList();
            if (lstPDHChiTiet == null || lstPDHChiTiet.Count == 0)
            {
                mmeInformationDetail.Text = "Bạn chưa chọn sản phẩm để làm bảng báo giá.";                
                isValid = false;
            }
            else
            {
                int i =0;
                grvPDHDetail.ClearColumnErrors();
                foreach (PhieuDatHangChiTiet pdhChiTiet in lstPDHChiTiet)
                {
                    grvPDHDetail.FocusedRowHandle = i;
                    if (pdhChiTiet.MasterItem == null)
                    {                        
                        grvPDHDetail.SetColumnError(gcPDHDetailItem, "Chọn sản phẩm cho phiếu báo giá.");
                        isValid = false;
                    }
                    if (pdhChiTiet.Quantity.GetValueOrDefault() == 0)
                    {
                        grvPDHDetail.SetColumnError(gcPDHQuantity, "Nhập số lượng đặt hàng.");
                        isValid = false;
                    }
                    i++;
                }
            }

            return isValid;
        }
        #endregion

        #region Event Handlers
        private void grvPDHDetail_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            try
            {
                if (e.Info.IsRowIndicator)
                {
                    if (e.RowHandle != GridControl.NewItemRowHandle && e.RowHandle != GridControl.AutoFilterRowHandle)
                    {
                        if (e.RowHandle < 0)
                        {
                            e.Info.DisplayText = "";
                        }
                        else
                        {
                            e.Info.DisplayText = (e.RowHandle + 1).ToString();
                        }
                    }
                    if (e.RowHandle == GridControl.AutoFilterRowHandle)
                    {
                        e.Info.ImageIndex = -1;
                        e.Info.DisplayText = "Filter";
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void FrmBangBaoGiaChiTiet_Load(object sender, EventArgs e)
        {
            try
            {
                SetDefaultValue();
                EnableControlToEdit();
                RegisterEventHandlers();
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePDHVendor_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.OK) // Hiển thị thông tin chi tiết của object
                {
                    if (luePDHVendor.EditValue != null && luePDHVendor.Text != string.Empty)
                    {
                        Vendor currentObject = luePDHVendor.Properties.GetDataSourceRowByKeyValue(luePDHVendor.EditValue) as Vendor;
                        if (currentObject != null)
                        {
                            DisplayInformationOfObject(currentObject);
                        }
                    }
                }
                else if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Ellipsis) // Hiển thị form quản lý và tạo mới object
                {
                    FrmVendor_List frm = new FrmVendor_List();
                    frm.RowSelected += frmVendor_RowSelected;
                    ViewManager.ShowView(frm);
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmVendor_RowSelected(object sender, Pharmacy.Ultilities.BaseEventArgs.RowSelectedArgs e)
        {
            try
            {
                LoadVendorList(e.CurrentSelectedRowID);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePDHMasterLocation_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.OK) // Hiển thị thông tin chi tiết của object
                {
                    if (luePDHMasterLocation.EditValue != null && luePDHMasterLocation.Text != string.Empty)
                    {
                        MasterLocation currentObject = luePDHMasterLocation.Properties.GetDataSourceRowByKeyValue(luePDHMasterLocation.EditValue) as MasterLocation;
                        if (currentObject != null)
                        {
                            DisplayInformationOfObject(currentObject);
                        }
                    }
                }
                else if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Ellipsis) // Hiển thị form quản lý và tạo mới object
                {
                    FrmMasterLocation_List frm = new FrmMasterLocation_List();
                    frm.RowSelected += frmMasterLocation_RowSelected;
                    ViewManager.ShowView(frm);
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmMasterLocation_RowSelected(object sender, Pharmacy.Ultilities.BaseEventArgs.RowSelectedArgs e)
        {
            try
            {
                LoadMasterLocationList(e.CurrentSelectedRowID);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePDHdetailItem_EditValueChanged(object sender, EventArgs e)
        {
            try
            {
                if ((sender as BaseEdit).EditValue != null)
                {
                    MasterItem item = luePDHdetailItem.GetDataSourceRowByKeyValue((sender as BaseEdit).EditValue) as MasterItem;
                    if (item != null)
                    {
                        PhieuDatHangChiTiet pdhDetail = grvPDHDetail.GetRow(grvPDHDetail.FocusedRowHandle) as PhieuDatHangChiTiet;
                        if (pdhDetail == null)
                        {
                            return;
                        }
                        if (grvPDHDetail.FocusedRowHandle < 0) // thêm mới
                        {
                            pdhDetail.UnitCost = 0;
                            pdhDetail.DiscountAmount = 0;
                            pdhDetail.DiscountRate = 0;
                            pdhDetail.VATRate = 0;
                            pdhDetail.VATAmount = 0;
                            pdhDetail.Amount = 0;
                        }
                        pdhDetail.MasterItem = item;
                        pdhDetail.UnitOfMeasure = item.UnitOfMeasure;
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePDHdetailItem_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Ellipsis)
                {
                    FrmMasterItem_List frm = new FrmMasterItem_List();
                    frm.RowSelected += frmMasterItem_RowSelected;
                    ViewManager.ShowView(frm);
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmMasterItem_RowSelected(object sender, Pharmacy.Ultilities.BaseEventArgs.RowSelectedArgs e)
        {
            try
            {
                luePDHdetailItem.DataSource = LoadItemList(e.CurrentSelectedRowID);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void btnDetailDelete_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Delete)
                {
                    PhieuDatHangChiTiet pdhDetail = grvPDHDetail.GetRow(grvPDHDetail.FocusedRowHandle) as PhieuDatHangChiTiet;
                    if (pdhDetail != null)
                    {
                        if(pdhDetail.EntityState != System.Data.EntityState.Added)
                            lstPhieuDatHangChiTietDeleted.Add(pdhDetail);
                        currentPhieuDatHang.PhieuDatHangChiTiets.Remove(pdhDetail);
                        CalculateAmountForPhieuDatHang();
                        grvPDHDetail.RefreshData();
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void grvPDHDetail_ShownEditor(object sender, EventArgs e)
        {
            try
            {
                DevExpress.XtraGrid.Views.Grid.GridView view;
                view = sender as DevExpress.XtraGrid.Views.Grid.GridView;
                if (view.FocusedColumn.Name == gcPDHDetailItem.Name)
                {
                    LookUpEdit lue1 = (LookUpEdit)view.ActiveEditor;
                    List<int> arrMasterItemIDs = new List<int>();
                    arrMasterItemIDs.Add(-1);
                    if (currentPhieuDatHang != null && currentPhieuDatHang.PhieuDatHangChiTiets != null && currentPhieuDatHang.PhieuDatHangChiTiets.Count > 0)
                    {
                        List<PhieuDatHangChiTiet> lstPhieuDatHangChiTiet = currentPhieuDatHang.PhieuDatHangChiTiets.ToList();
                        for (int i = 0; i < lstPhieuDatHangChiTiet.Count; i++)
                        {
                            //if (i == gvSOLineItem.FocusedRowHandle) continue;
                            PhieuDatHangChiTiet pdhDetail = lstPhieuDatHangChiTiet[i];
                            if (pdhDetail != null && pdhDetail.MasterItem != null)
                                arrMasterItemIDs.Add(pdhDetail.MasterItem.ID);
                        }
                    }
                    lue1.Properties.DataSource = rMasterItem.AsQueryable()
                                                            .Where(item => !(arrMasterItemIDs.Contains(item.ID)))
                                                            .ToList();
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void grvPDHDetail_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            try
            {
                PhieuDatHangChiTiet pdhChiTiet = grvPDHDetail.GetRow(grvPDHDetail.FocusedRowHandle) as PhieuDatHangChiTiet;
                if (pdhChiTiet != null)
                {
                    if (e.Column.FieldName == gcPDHPrice.FieldName)
                    {
                        pdhChiTiet.UnitCost = Convert.ToDecimal(e.Value);
                    }
                    if (e.Column.FieldName == gcPDHVAT.FieldName)
                    {
                        applyAllVAT = false;
                        pdhChiTiet.VATRate = Convert.ToDecimal(e.Value);
                    }
                    else if (e.Column.FieldName == gcPDHChietKhau.FieldName)
                    {
                        applyAllDiscount = false;
                        pdhChiTiet.DiscountRate = Convert.ToDecimal(e.Value);
                    }
                    if (grvPDHDetail.FocusedRowHandle < 0)
                    {
                        CalculateAmountForPhieuDatHangDetail(pdhChiTiet);
                        decimal totalAmountBeforeVAT = currentPhieuDatHang.TotalAmountBeforeVAT.GetValueOrDefault() + pdhChiTiet.UnitCost.GetValueOrDefault();
                        decimal totalVATAmount = currentPhieuDatHang.TotalVATAmount.GetValueOrDefault() + pdhChiTiet.VATAmount.GetValueOrDefault();
                        decimal totalDiscountAmount = currentPhieuDatHang.TotalDiscountAmount.GetValueOrDefault() + pdhChiTiet.DiscountAmount.GetValueOrDefault();
                        decimal totalAmount = currentPhieuDatHang.TotalAmount.GetValueOrDefault() + pdhChiTiet.Amount.GetValueOrDefault();

                        txtPDHTienTruocVAT.EditValue = currentPhieuDatHang.TotalAmountBeforeVAT = totalAmountBeforeVAT;
                        txtPDHTienCK.EditValue = currentPhieuDatHang.TotalDiscountAmount = totalDiscountAmount;
                        //currentPhieuBaoGia.TotalDiscountRate = totalDiscountRate;
                        txtPDHTienVAT.EditValue = currentPhieuDatHang.TotalVATAmount = totalVATAmount;
                        //currentPhieuBaoGia.TotalVATRate = totalVATRate;
                        txtPDHTienTongCong.EditValue = currentPhieuDatHang.TotalAmount = totalAmount;
                    }
                    else
                    {
                        CalculateAmountForPhieuDatHang();
                    }
                }

            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void txtPDHTienVAT_Click(object sender, EventArgs e)
        {
            txtPDHTienVAT.ShowPopup();
        }

        private void txtPDHTienCK_Click(object sender, EventArgs e)
        {
            txtPDHTienCK.ShowPopup();
        }

        private void txtPDHTienVAT_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
                {
                    applyAllVAT = true;
                    FrmCalculateDiscountAndVAT frm = new FrmCalculateDiscountAndVAT();
                    frm.VATAmount = currentPhieuDatHang.TotalVATAmount.GetValueOrDefault();
                    frm.VATRate = currentPhieuDatHang.TotalVATRate.GetValueOrDefault();
                    frm.DiscountAmount = currentPhieuDatHang.TotalDiscountAmount.GetValueOrDefault();
                    frm.DiscountRate = currentPhieuDatHang.TotalDiscountRate.GetValueOrDefault();
                    frm.TotalAmountBeforeVAT = currentPhieuDatHang.TotalAmountBeforeVAT.GetValueOrDefault();
                    frm.TotalAmount = Convert.ToDecimal(currentPhieuDatHang.TotalAmount.GetValueOrDefault());
                    frm.SubmittedForm += new FrmCalculateDiscountAndVAT.OnSubmittedForm(frmApplyDiscountAndVAT_SubmittedForm);
                    frm.ShowDialog();
                    applyAllVAT = false;
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void txtPDHTienCK_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
                {
                    if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
                    {
                        applyAllDiscount = true;
                        FrmCalculateDiscountAndVAT frm = new FrmCalculateDiscountAndVAT();
                        frm.VATAmount = currentPhieuDatHang.TotalVATAmount.GetValueOrDefault();
                        frm.VATRate = currentPhieuDatHang.TotalVATRate.GetValueOrDefault();
                        frm.DiscountAmount = currentPhieuDatHang.TotalDiscountAmount.GetValueOrDefault();
                        frm.DiscountRate = currentPhieuDatHang.TotalDiscountRate.GetValueOrDefault();
                        frm.TotalAmountBeforeVAT = currentPhieuDatHang.TotalAmountBeforeVAT.GetValueOrDefault();
                        frm.TotalAmount = Convert.ToDecimal(currentPhieuDatHang.TotalAmount.GetValueOrDefault());
                        frm.SubmittedForm += new FrmCalculateDiscountAndVAT.OnSubmittedForm(frmApplyDiscountAndVAT_SubmittedForm);
                        frm.ShowDialog();
                        applyAllDiscount = false;
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmApplyDiscountAndVAT_SubmittedForm(object sender, Core.CustomEventArgs.DiscountAndVATArgs e)
        {
            try
            {
                ApplyAllDiscountAndVAT(e.DiscountRate, e.VATRate);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            try
            {
                CurrentAction = Enums.ActionForm.New;
                ResetAllData();
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                bool result = true;
                string message = string.Empty;
                if (ValidateData() && grvPDHDetail.HasColumnErrors == false)
                {
                    ViewManager.CreateWaitDialog();
                    ViewManager.SetWaitDialogCaption(SR.Instance.GetString(Constant.ENT_MASTERITEM), "Saving...");
                    BindControlToData();
                    if (CurrentAction == Enums.ActionForm.New)
                    {
                        pdhBO.CreateNewPhieuDatHang(currentPhieuDatHang);
                        CurrentAction = Enums.ActionForm.View;
                        ResetAllData();
                    }
                    if (CurrentAction == Enums.ActionForm.Edit)
                    {
                        result = pdhBO.EditPhieuDatHang(currentPhieuDatHang, lstPhieuDatHangChiTietDeleted, out message);
                        if (result == false)
                        {
                            MessageBox.Show(message);
                            return;
                        }
                        else
                            lstPhieuDatHangChiTietDeleted.Clear();
                    }
                }

            }
            catch (PessimisticLockingException ex)
            {
                LockingInfo lockInfo = ex.LockDataInfo.ToList()[0];
                MessageBox.Show(string.Format(SR.Instance.GetString(Constant.MSG_LOCKBYANOTHERUSER)
                                                , SR.Instance.GetString(Constant.ENT_PHIEUDATHANG)
                                                , currentPhieuDatHang.Code
                                                , lockInfo.UserName, lockInfo.ComputerName));
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
                this.Close();
            }
            finally
            {
                ViewManager.CloseWaitDialog();
            }   
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                ResetAllData();
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                bool result = true;
                string message = string.Empty;
                if (currentPhieuDatHang != null && CurrentAction == Enums.ActionForm.Edit)
                {
                    if (MessageBox.Show(SR.Instance.GetString(Constant.MSG_CONFIRMDELETEOBJECT), "", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                    {
                        ViewManager.CreateWaitDialog();
                        ViewManager.SetWaitDialogCaption(SR.Instance.GetString(Constant.ENT_MASTERITEM), "Deleting...");
                        result = pdhBO.DeletePhieuDatHang(currentPhieuDatHang.ID, out message);
                        if (result == false)
                        {
                            MessageBox.Show(message);
                            return;
                        }
                        CurrentAction = Enums.ActionForm.New;
                        BindDataToControl();
                    }
                }
            }
            catch (PessimisticLockingException ex)
            {
                LockingInfo lockInfo = ex.LockDataInfo.ToList()[0];
                MessageBox.Show(string.Format(SR.Instance.GetString(Constant.MSG_LOCKBYANOTHERUSER)
                                                , SR.Instance.GetString(Constant.ENT_PHIEUBAOGIA)
                                                , currentPhieuDatHang.Code
                                                , lockInfo.UserName, lockInfo.ComputerName));
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
                this.Close();
            }
            finally
            {
                ViewManager.CloseWaitDialog();
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void txtPDHTienCK_EditValueChanged(object sender, EventArgs e)
        {
            try
            {
                decimal discountAmount = Convert.ToDecimal(txtPDHTienCK.EditValue);
                if (currentPhieuDatHang.TotalAmountBeforeVAT.GetValueOrDefault() > 0)
                {
                    decimal discountRate = (discountAmount / currentPhieuDatHang.TotalAmountBeforeVAT.GetValueOrDefault()) * 100;
                    ApplyAllDiscountAndVAT(discountRate, 0);
                    applyAllDiscount = false;
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void txtPDHTienVAT_EditValueChanged(object sender, EventArgs e)
        {
            try
            {
                decimal VATAmount = Convert.ToDecimal(txtPDHTienVAT.EditValue);
                decimal discountAmount = Convert.ToDecimal(txtPDHTienCK.EditValue);
                if (currentPhieuDatHang.TotalAmountBeforeVAT.GetValueOrDefault() - discountAmount > 0)
                {
                    decimal VATRate = (VATAmount / (currentPhieuDatHang.TotalAmountBeforeVAT.GetValueOrDefault() - discountAmount)) * 100;
                    ApplyAllDiscountAndVAT(0, VATRate);
                    applyAllVAT = true;
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }
        #endregion        

        private void txtPDHTienCK_KeyPress(object sender, KeyPressEventArgs e)
        {
            applyAllDiscount = true;
            applyAllVAT = false;
        }

        private void txtPDHTienVAT_KeyPress(object sender, KeyPressEventArgs e)
        {
            applyAllDiscount = false;
            applyAllVAT = true;
        }

        private void grvPDHDetail_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs e)
        {
            try
            {
                PhieuDatHangChiTiet pdhChiTiet = e.Row as PhieuDatHangChiTiet;
                grvPDHDetail.ClearColumnErrors();
                if (pdhChiTiet != null)
                {
                    if (pdhChiTiet.Quantity.GetValueOrDefault() <= 0)
                    {
                        grvPDHDetail.SetColumnError(gcPDHQuantity, "Nhập số lượng đặt hàng.");
                        e.Valid = false;
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void grvPDHDetail_InvalidRowException(object sender, DevExpress.XtraGrid.Views.Base.InvalidRowExceptionEventArgs e)
        {
            e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction;
        }
    }
}